观察者模式与spring guava事件 您所在的位置:网站首页 观察者模式 spring 观察者模式与spring guava事件

观察者模式与spring guava事件

2024-03-09 00:12| 来源: 网络整理| 查看: 265

1. 观察者模式

观察者模式,也叫发布/订阅(Publish/Subscribe)模式,观察者模式比较简单,但是非常常用,当然也非常实用。

观察者模式最大的好处是,当业务逻辑变得复杂之后,通过观察者模式可以减轻耦合。

举个简单的例子,一个简单的用户充值事件,当业务复杂之后,除了处理订单之外,可能还需要送券、奖励积分金币、提示VIP等级、送抽奖等激励活动、处理邀请码、发送重要事件记录日志、处理重要事件异常操作等等。

如果这些逻辑都放在“用户充值”这个流程之中,那肯定逻辑耦合爆炸。所以,一般不这么干。

如果用户规模大,做了服务拆分,那就走消息系统,这本质上还是观察者模式。

如果没有做服务拆分,像guava的EventBus这样的观察者模式组件就派上用场了。

组件说明Subject抽象主题、被观察者,一般是事件,例如用户充值、配置变化、VIP等级提升等事件ConcreteSubject主要提供观察者注册、取消,以及当事件发送时,回调已经注册的观察者的接口Observer抽象观察者ConcrereObserver具体观察者,在具体事件、如用户充值这个事情发送之后要执行的具体逻辑

观察者模式 观察者模式

2. Guava EventBus

首先,可以先定义一些自定义事件,例如用户充值:

import vip.mycollege.tool.guava.bean.ChargeBean; import vip.mycollege.tool.guava.bean.UserBean; import java.io.Serializable; public class ChargeEvent implements Serializable{ private static final long serialVersionUID = -8775590840527884827L; private UserBean user; private ChargeBean charge; public UserBean getUser() { return user; } public void setUser(UserBean user) { this.user = user; } public ChargeBean getCharge() { return charge; } public void setCharge(ChargeBean charge) { this.charge = charge; } }

然后,添加观察者,也就是当事件发生时候,需要执行的逻辑:

import com.google.common.eventbus.Subscribe; import vip.mycollege.tool.guava.event.ChargeEvent; import java.util.concurrent.TimeUnit; public class CommonListener { @Subscribe public void dealChargeGold(ChargeEvent event){ try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("处理gold"); } @Subscribe public void dealChargeLevel(ChargeEvent event){ System.out.println("处理level"); } }

guava中的观察者非常简单,不需要实现什么接口,只需要添加@Subscribe方法注解就可以了,方法的参数就是要观察的具体事件。

接下来需要Subject,在guava中也非常简单:

import com.google.common.eventbus.AsyncEventBus; import com.google.common.eventbus.EventBus; import vip.mycollege.tool.guava.event.ChargeEvent; import vip.mycollege.tool.guava.listener.CommonListener; import java.util.concurrent.Executors; public class EventBusStart { public static void main(String[] args) { EventBus eventBus = new EventBus(); eventBus.register(new CommonListener()); eventBus.post(new ChargeEvent()); AsyncEventBus asyncEventBus = new AsyncEventBus(Executors.newCachedThreadPool()); asyncEventBus.register(new CommonListener()); asyncEventBus.post(new ChargeEvent()); System.out.println("main"); } }

EventBus是同步事件,它使用一个main线程顺序的分发Event。

AsyncEventBus可以指定一个线程池来异步分发Event。使用AsyncEventBus需要注意业务逻辑中应该没有先后顺序约束。

**register方法:**注册时间,具体的就是去扫描参数类中的@Subscribe注解方法。

**post方法:**具体事件发生时候,触发,然后EventBus就去回调register中观察了该事件(参数和该事件类型一致)的@Subscribe方法。

3. Spring Event

除了guava之外,Spring套装也提供了观察者模式的实现,重要的类:

ApplicationEvent:抽象事件,具体事件可以继承这个类ApplicationListener:观察者,需要实现onApplicationEvent方法,处理具体的事件发生逻辑ApplicationEventPublisher:发布事件,具体事件发生时,通过它触发

还是一个简单的实例:

import org.springframework.context.ApplicationEvent; public class LoginEvent extends ApplicationEvent { public LoginEvent(Object source) { super(source); } }

观察者:

import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import java.util.Map; @Component public class LoginEventListener implements ApplicationListener { @Override public void onApplicationEvent(LoginEvent event) { Map map = (Map) event.getSource(); System.out.println(map.keySet()); System.out.println(map.values()); } }

除了要继承ApplicationListener,还需要添加@Component之类的注解,这样通过注解扫描才能创建这个类。

事件发布:

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; import java.util.HashMap; @Component public class LoginLogic { @Autowired private ApplicationEventPublisher applicationEventPublisher; public void login(){ HashMap params = new HashMap(); params.put("name","tim"); params.put("age","25"); LoginEvent loginEvent = new LoginEvent(params); applicationEventPublisher.publishEvent(loginEvent); } }

Spring在启动的时候,会自动创建一个ApplicationEventPublisher,所以我们可以直接注入就可以了。

当具体的事件发生时候,直接通过ApplicationEventPublisher触发响应的事件就好了,只需要简单的封装一下事件参数。

Spring的观察者模式比guava的稍微复杂一些,如果仅仅是需要观察者模式,建议使用guava,如果是已经使用了Spring,需要观察者模式,可以考虑使用Spring自带的观察者模式实现。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有